home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mac Power 1996 October
/
MACPOWER-1996-10.ISO.7z
/
MACPOWER-1996-10.ISO
/
AMUG
/
Internet_31
/
NetCacheResolver 0.9d6
/
NetCacheResolver 0.9d6 ト
/
library
/
NCR_Resolve.c
< prev
next >
Wrap
Text File
|
1996-05-12
|
14KB
|
433 lines
// NetCache Resolver, 1995-96 (C) Mizutori Tetsuya
// - NCR_Resolve.c, October 8, 1995, May 12 1996
// This document is pretty printed in 10-point Geneva font.
#include "NCR_Basic.h"
#include "NCR_Resolve.h"
#include "NCR_File.h"
#include "NCR_Error.h"
#ifdef DEBUG
#include "NCR_Message.h"
#endif /*DEBUG */
// definition
// in Header
#define OFFS_BLOCKSIZE 0x00000C
#define OFFS_NUMBPAIRS 0x000038
// start with pURL
#define OFFS_URL_STR 4
// start with pFInfo
#define OFFS_CACHE_INFO 4
#define WIDTH_CACHE_INFO 25 // 5*sizeof(long) + 1 + sizeof(long)
#define OFFS_DATE1 OFFS_CACHE_INFO + 4
#define OFFS_DATE2 OFFS_CACHE_INFO + 8
#define OFFS_FILESIZE OFFS_CACHE_INFO + 16
#define OFFS_CACHE_STR OFFS_CACHE_INFO + WIDTH_CACHE_INFO
#define OFFS_DOC_INFO OFFS_CACHE_STR + 4 /* +#(OFFS_CACHE_STR) */
//#define WIDTH_DOC_INFO 29 // October 8, 1995; char[1]+long[7]
#define WIDTH_DOC_INFO 17 // May 12, 1996; char[1]+long[4]
#define OFFS_DOC_COUNT OFFS_DOC_INFO + WIDTH_DOC_INFO + 4 // +char[1]+long[5]
#define OFFS_EXPORT_STR OFFS_DOC_INFO + WIDTH_DOC_INFO
#define OFFS_EXDATA_STR OFFS_EXPORT_STR + 4/* +#(OFFS_EXPORT_STR) */
// #define OFFS_FORM_STR OFFS_DOC_INFO + WIDTH_DOC_INFO // October 8, 1995
#define OFFS_FORM_STR OFFS_DOC_INFO+ 4/* +#(OFFS_EXPORT_STR) */ + 4/* +#(OFFS_EXDATA_STR) */
#define OFFS_TYPE_STR OFFS_FORM_STR + 4 /* +#(OFFS_FORM_STR) */
typedef struct { // If len is zero, then no allocation space for str[] is occupied.
unsigned long len; // length of string, including the terminator '¥0'
unsigned char str[]; // character string, teminated by '¥0'
} QString; // size of QString is at least 4 bytes, which is the case that len is zero.
typedef struct { // length of DummyData record must be determined dynamically
unsigned char dumchar; // the first filler character
unsigned char dumstr[];
} DummyData;
typedef struct {
unsigned long size; // total size occupied by this record, in bytes
QString url; // e.g. "http://www.a.b.c/index.html"
unsigned long _end; // ? = 0x0000 (terminator ?)
} _URL_Record;
typedef struct {
unsigned long size; // total size occupied by this record, in bytes
// OFFS_CACHE_INFO
unsigned long _1; // ? = 0x0003
unsigned long date1; // time stamp 1 (creation ?)
unsigned long date2; // time stamp 2 (modification ?)
unsigned long _2; // ? = 0x0000
unsigned long filesize; // cache file size, in bytes
unsigned char _3; // ? = 0x00, odd byte!
unsigned long _4; // ? = 0x0000 (count-1 for strings followed ?)
// OFFS_CACHE_STR
QString cache; // e.g. "cache123000.html"
// OFFS_DOC_INFO
/***** October 8, 1995 *****
unsigned long _5[6]; // ? = {0,1,0,0,0,0}
unsigned char _6; // ? = 0x00, odd byte!
unsigned long _7; // ? = 0x0000 or 0x0001 (count-1 for strings followed ?)
*****/
/***** May 12, 1995 *****/
unsigned long _5; // ? = 0x0000
unsigned char _6; // ? = 0x01, odd byte!
unsigned long _51; // ? = 0x0000 or 0x0002
unsigned long _52; // ? = 0x0000 or 0x0008
unsigned long _53; // ? = 0x0000 or 0x0028
// OFFS_EXPORT_STR
QString export; // e.g. "RC4-Export"
// OFFS_EXDATA_STR
QString exdata; // e.g. "???Data Export Inc. v.1.0..."
unsigned long _7; // ? = 0x0000 or 0x0001 (count-1 for strings followed ?)
// OFFS_FORM_STR
QString form; // e.g. "Content-type: application..."
// OFFS_TYPE_STR
QString type; // e.g. "text/html"
unsigned char _8[9]; // ? = {all 0x00's}, odd bytes!
unsigned long fsize; // cache file size, in bytes (same value to .filesize)
DummyData _9; // ? = filled by 0x00's, even or odd bytes!
unsigned long _end; // ? = 0x0000 (terminator ?)
} _FInfo_Record;
typedef struct {
unsigned long url;
unsigned long cache;
unsigned long form;
unsigned long type;
unsigned long sizeurl;
unsigned long sizecache;
unsigned long sizeform;
unsigned long sizetype;
unsigned long filesize;
unsigned long date1, date2;
} IndexTableRecord, *IndexTablePtr, **IndexTableHandle;
// prototype
static unsigned long GetLongLH (unsigned char *p );
static OSErr SetupHeader ( Handle theHndl );
static OSErr DoHandleCacheData ( Handle theHndlData, Handle theHndl );
static OSErr MakeRecord ( Handle theHndl, unsigned long startOffset, long index, IndexTableRecord *table );
static OSErr PrintRecord ( Handle theHndl, long index, IndexTableRecord *table );
static OSErr InsertRecord ( Handle theHndl, Handle theHndl2, long index, IndexTableRecord *table );
static OSErr InsertHeader ( Handle theHndl, Handle theHndl2 );
static OSErr AppendString ( Handle theHndl, const char *str, Size length );
/***** General functions *****/
#define GetWordHL(p) ( (unsigned short) * ( (unsigned short *) (p) ) )
#define GetLongHL(p) ( (unsigned long) * ( (unsigned long *) (p) ) )
static unsigned long GetLongLH (unsigned char *p )
{
unsigned long n = 0;
unsigned char *q;
q = (unsigned char *) &n;
q[0] = p[3];
q[1] = p[2];
q[2] = p[1];
q[3] = p[0];
return n;
}
/***** Read Database from the file *****/
OSErr GetRecordFromFile ( FSSpec *theFSSpec, FInfo *theFInfo, Handle theHndl, long *count )
{
Handle theHndlData = nil;
long datasize;
OSType fdType = 'DBMC'; // read from 'STR#'
Str31 strFdType;
OSErr err = noErr;
// read database from the file
GetIndString( strFdType, STRID_CACHE, STRIX_CCACHETYPE );
BlockMove( &strFdType[1], &fdType, 4 );
err = FSpGetFInfo( theFSSpec, theFInfo );
if ( err != noErr ) { ErrorMessageFS( err, false ); goto out; }
if ( theFInfo->fdType != fdType ) {
err = errAEWrongDataType;
ErrorMessageAE( err, false ); goto out; }
theHndlData = NewHandleClear( 0 ); // create a Handle 'theHndlData'
if ( (err=MemError()) != noErr ) { ErrorMessageMEM( err, true ); }
err = ReadFile( theFSSpec, theFInfo, theHndlData, &datasize );
if ( err != noErr ) { ErrorMessageFS( err, false ); goto out; }
// convert 'theHndlData' to 'theHndl'
err = DoHandleCacheData( theHndlData, theHndl );
*count = GetHandleSize( theHndl );
out:
if ( theHndlData != nil ) DisposeHandle( theHndlData ); // dispose the Handle 'theHndlData'
return err;
}
/***** do Handle Data *****/
// globals
unsigned long gHndlSize = 0; // set by GetHandleSize()
unsigned long gBlockSize = 0x004000; // read from at the offset 'OFFS_BLOCKSIZE'
static OSErr SetupHeader ( Handle theHndl )
{
if ( gHndlSize != 0 ) return noErr;
gHndlSize = GetHandleSize( theHndl );
gBlockSize = GetLongHL((unsigned char *)*theHndl+OFFS_BLOCKSIZE );
return noErr;
}
static OSErr DoHandleCacheData ( Handle theHndlData, Handle theHndl )
{
IndexTableRecord table;
unsigned long n, index;
unsigned long startOffset;
OSErr err;
#ifdef DEBUG
Message("DoHandleData() start¥n");
#endif /* DEBUG */
SetupHeader( theHndlData );
InsertHeader( theHndlData, theHndl );
n = 0;
startOffset = gBlockSize;
while ( startOffset < gHndlSize ) {
for ( index=1; ; index++) {
err = MakeRecord( theHndlData, startOffset, index, &table );
if ( err == nilHandleErr ) break;
if ( err != noErr ) continue;
// PrintRecord( theHndlData, n, &table );
InsertRecord( theHndlData, theHndl, n, &table );
n++;
}
startOffset += gBlockSize;
}
#ifdef DEBUG
Message("DoHandleData() end¥n");
#endif /* DEBUG */
return noErr;
}
/***** Make Record *****/
#define ALLOWANCE_TOC 4096
#define ALLOWANCE_LENGH 255
// index should begin with 1, not 0
static OSErr MakeRecord ( Handle theHndl, unsigned long startOffset, long index, IndexTableRecord *table )
{
long count;
long offsetURL, offsetFInfo;
unsigned char *pHeap, *pHashTable, *pURL, *pFInfo;
long sizeURL, sizeCache, sizeForm, sizeType;
unsigned char *strURL, *strCache, *strForm, *strType;
unsigned long filesize, date1, date2;
unsigned long exportsize, exdatasize;
OSErr err = noErr;
HLock( theHndl );
pHeap = (unsigned char *) *theHndl;
pHashTable = (unsigned char *) *theHndl + startOffset;
count = GetWordHL(pHashTable);
if ( count <= 0 || ALLOWANCE_TOC <= count ) { err = nilHandleErr; goto out; }
count /= 2;
if ( index < 1 || count < index ) { err = nilHandleErr; goto out; }
index -= 1;
// for URL
// offsetURL = GetWordHL( pHashTable + 4*index+2 );
pURL = pHashTable + GetWordHL( pHashTable + 4*index+2 );
//#define OFFS_URL_STR 4
offsetURL = OFFS_URL_STR;
sizeURL = GetLongLH(pURL+offsetURL);
strURL = (unsigned char *) (pURL+offsetURL+sizeof(long));
if ( sizeURL <= 0 || ALLOWANCE_LENGH < sizeURL ) { err = paramErr; goto out; }
offsetURL += sizeof(long) + sizeURL;
// for File Info
pFInfo = pHashTable + GetWordHL( pHashTable + 4*index+4 );
//#define OFFS_CACHE_INFO 4
//#define WIDTH_CACHE_INFO 25
//#define OFFS_CACHE_STR OFFS_CACHE_INFO + WIDTH_CACHE_INFO
offsetFInfo = OFFS_CACHE_STR;
// cache filename
sizeCache = GetLongLH(pFInfo+offsetFInfo);
strCache = (unsigned char *) (pFInfo+offsetFInfo+sizeof(long));
if ( sizeCache <= 0 || ALLOWANCE_LENGH < sizeCache ) { err = paramErr; goto out; }
offsetFInfo += sizeof(long) + sizeCache;
#ifdef COMMENT // October 8, 1995
//#define OFFS_DOC_INFO OFFS_CACHE_STR + 4 /* +#(OFFS_CACHE_STR) */
//#define WIDTH_DOC_INFO 29 // char[1]+long[7]
//#define OFFS_FORM_STR OFFS_DOC_INFO + WIDTH_DOC_INFO
//#define OFFS_TYPE_STR OFFS_FORM_STR + 4 /* +#(OFFS_FORM_STR) */
offsetFInfo += WIDTH_DOC_INFO;
#endif // COMMENT
// May 12, 1996
//#define OFFS_DOC_INFO OFFS_CACHE_STR + 4 /* +#(OFFS_CACHE_STR) */
//#define WIDTH_DOC_INFO 17 // char[1]+long[4]
//#define OFFS_DOC_COUNT OFFS_DOC_INFO + WIDTH_DOC_INFO + 4 // +char[1]+long[5]
//#define OFFS_EXPORT_STR OFFS_DOC_INFO + WIDTH_DOC_INFO
//#define OFFS_EXDATA_STR OFFS_EXPORT_STR + 4/* +#(OFFS_EXPORT_STR) */
//#define OFFS_FORM_STR OFFS_DOC_INFO+ 4/* +#(OFFS_EXPORT_STR) */ + 4/* +#(OFFS_EXDATA_STR) */
//#define OFFS_TYPE_STR OFFS_FORM_STR + 4 /* +#(OFFS_FORM_STR) */
offsetFInfo += WIDTH_DOC_INFO;
exportsize = GetLongLH( pFInfo+offsetFInfo );
offsetFInfo += sizeof(long) + exportsize;
exdatasize = GetLongLH( pFInfo+offsetFInfo );
offsetFInfo += sizeof(long) + exdatasize;
offsetFInfo += sizeof(long);
// content-type (Can be Null string!)
sizeForm = GetLongLH( pFInfo+offsetFInfo );
strForm = (unsigned char *) (pFInfo+offsetFInfo+sizeof(long));
if ( sizeForm < 0 || ALLOWANCE_LENGH < sizeForm ) { err = paramErr; goto out; }
offsetFInfo += sizeof(long) + sizeForm;
// type (Can be Null string!)
sizeType = GetLongLH( pFInfo+offsetFInfo );
strType = (unsigned char *) (pFInfo+offsetFInfo+sizeof(long));
if ( sizeType < 0 || ALLOWANCE_LENGH < sizeType ) { err = paramErr; goto out; }
offsetFInfo += sizeof(long) + sizeType;
table->url = (unsigned long) strURL - (unsigned long) pHeap;
table->cache = (unsigned long) strCache - (unsigned long) pHeap;
table->form = (unsigned long) strForm - (unsigned long) pHeap;
table->type = (unsigned long) strType - (unsigned long) pHeap;
table->sizeurl = ( sizeURL < 1 ? 0 : sizeURL - 1 ) ; // truncate the terminator '¥0'
table->sizecache = ( sizeCache < 1 ? 0 : sizeCache - 1 );
table->sizeform = ( sizeForm < 1 ? 0 : sizeForm - 1 );
table->sizetype = ( sizeType < 1 ? 0 : sizeType - 1 );
table->date1 = GetLongLH( pFInfo+OFFS_DATE1 );
table->date2 = GetLongLH( pFInfo+OFFS_DATE2 );
table->filesize = GetLongLH( pFInfo+OFFS_FILESIZE );
//#define OFFS_DATE1 OFFS_CACHE_INFO + 4
//#define OFFS_DATE2 OFFS_CACHE_INFO + 8
//#define OFFS_FILESIZE OFFS_CACHE_INFO + 16
out:
HUnlock( theHndl );
return err;
}
static OSErr PrintRecord ( Handle theHndl, long index, IndexTableRecord *table )
{
unsigned char *pHeap;
HLock( theHndl );
pHeap = (unsigned char *) *theHndl;
#ifdef DEBUG
Message("[%ld] cache=$%04X url=$%04X type=$%04X size=%ld¥n",
index, (short) table->cache, (short) table->url, (short) table->type, table->filesize);
Message("Cache:%ld('%s') ", table->sizecache, pHeap+table->cache);
Message("Type:%ld('%s')¥n", table->sizetype, pHeap+table->type);
Message("URL:%ld('%s')¥n", table->sizeurl, pHeap+table->url);
#endif /* DEBUG */
HUnlock( theHndl );
return noErr;
}
#define TAB "¥t"
#define EOL "¥r"
static OSErr InsertRecord ( Handle theHndl, Handle theHndl2, long index, IndexTableRecord *table )
{
unsigned char *pHeap;
Str255 text;
HLock( theHndl );
pHeap = (unsigned char *) *theHndl;
// for item 1 (some code '0')
AppendString( theHndl2, "0" TAB, 2 );
// for item 2 (date1)
NumToString(table->date1, text);
AppendString( theHndl2, (char *) &text[1], text[0] );
AppendString( theHndl2, TAB, 1 );
// for item 3 (date2)
NumToString(table->date2, text);
AppendString( theHndl2, (char *) &text[1], text[0] );
AppendString( theHndl2, TAB, 1 );
// for item 4 ("cache12300")
AppendString( theHndl2, (char *) pHeap+table->cache, table->sizecache );
AppendString( theHndl2, TAB, 1 );
// for item 5 ("URL")
AppendString( theHndl2, (char *) pHeap+table->url, table->sizeurl );
AppendString( theHndl2, TAB, 1 );
// for item 6 (file/type)
AppendString( theHndl2, (char *) pHeap+table->type, table->sizetype );
AppendString( theHndl2, TAB, 1 );
// for item 7 (format ?)
// AppendString( theHndl2, (char *) pHeap+table->form, table->sizeform );
AppendString( theHndl2, TAB, 1 );
// for item 8 (file size)
NumToString(table->filesize, text);
AppendString( theHndl2, (char *) &text[1], text[0] );
// for item 9 thru 10 (empty items)
AppendString( theHndl2, TAB TAB, 2 );
// for CR
AppendString( theHndl2, EOL, 1 );
HUnlock( theHndl );
return noErr;
}
static OSErr InsertHeader ( Handle theHndl, Handle theHndl2 )
{
Str255 text;
// for header line
GetIndString( text, STRID_CACHE, STRIX_FORMAT );
AppendString( theHndl2, (char *) &text[1], text[0] );
// for CR
AppendString( theHndl2, EOL, 1 );
return noErr;
}
static OSErr AppendString ( Handle theHndl, const char *str, Size length )
{
unsigned long n;
OSErr err;
n = GetHandleSize( theHndl );
SetHandleSize( theHndl, n+length );
if ( (err=MemError()) != noErr )
ErrorMessageMEM( err, true );
BlockMove( str, (unsigned char *) *theHndl + n, length );
return err;
}
// end of program